package ase.assignment.sts.api;

import java.rmi.RemoteException;

import ase.assignment.sts.utils.STSConstants;

/**
 * Factory proxy is to delegate the invocation to the active factory
 * implementation.
 * 
 * @author Lionel
 * 
 */
public class HandlerFactoryProxy implements HandlerFactory {
	/**
	 * singleton
	 * 
	 */
	private static HandlerFactoryProxy instance;

	/** JDBC implementation. It's always available. */
	private HandlerFactory jdbc;

	/**
	 * WebService implementation. It's only available after you have started
	 * Axis and deployed services. You could run WSBuild.xml by ant to deploy
	 * all services. It will delegate to JDBC implementation.
	 */
	private HandlerFactory ws;

	/**
	 * RMI implementation. It's only available after you start rmiregistry. It
	 * will delegate to WebService implementation.
	 */
	private HandlerFactory rmi;

	private HandlerFactory active;

	private HandlerFactoryProxy() {

	}

	public static synchronized HandlerFactoryProxy instance() {
		if (instance == null) {
			instance = new HandlerFactoryProxy();
			try {
				Class factoryClass = Class.forName(STSConstants.properties
						.getProperty("factory_db"));
				instance.jdbc = (HandlerFactory) factoryClass.newInstance();

				factoryClass = Class.forName(STSConstants.properties
						.getProperty("factory_rmi"));

				instance.rmi = (HandlerFactory) factoryClass.newInstance();

				factoryClass = Class.forName(STSConstants.properties
						.getProperty("factory_ws"));
				instance.ws = (HandlerFactory) factoryClass.newInstance();

				if (instance.jdbc.isActive()) {
					instance.active = instance.jdbc;
					System.out.println("JDBC is available.");
				}
				if (instance.ws.isActive()) {
					instance.active = instance.ws;
					System.out.println("Web Service is available.");
				}
				if (instance.rmi.isActive()) {
					instance.active = instance.rmi;
					System.out.println("RMI is available.");
				}

			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return instance;
	}

	public CustomerHandler getCustomerHandler() throws RemoteException {
		if (active != null) {
			return active.getCustomerHandler();
		}
		return null;
	}

	public PortfolioHandler getPortfolioHandler() throws RemoteException {
		if (active != null) {
			return active.getPortfolioHandler();
		}
		return null;
	}

	public StockHandler getStockHandler() throws RemoteException {
		if (active != null) {
			return active.getStockHandler();
		}
		return null;
	}

	public boolean isActive() throws RemoteException {
		if (active != null) {
			return active.isActive();
		}
		return false;
	}

}
